/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.persistence.sql;

import java.math.BigDecimal;
import java.util.HashMap;

import org.telosys.persistence.TelosysPersistenceException;

public enum CriterionType {
	
    UNKNOWN("UNKNOWN"),

    BOOLEAN("BOOLEAN"),

    BYTE("BYTE"),
    SHORT("SHORT"),
    INT("INT"),
    LONG("LONG"),
    
    FLOAT("FLOAT"),
    DOUBLE("DOUBLE"),

    STRING("STRING"),
    
    DATE("DATE"),
    TIMESTAMP("TIMESTAMP"),
    TIME("TIME"),
    
    BIGDECIMAL("BIGDECIMAL");

	private final String typeName ;	

	private CriterionType(String typeName ) {
		this.typeName = typeName ;
		
	}

	public String getName() {
		return typeName ;
	}
	
	public Object toObject(String s) {
        if ( null == s  )  {
            return null ;
        }

        if ( this == STRING ) {
        	return s ; // Returns the String "as is"
        }
        
		try {
			return stringValueToObject(s.trim());
	    } catch (Exception e)
	    {
	        throw new TelosysPersistenceException("Cannot convert string '" + s + "' to " + typeName + " object", e);
	    }
	}
	
	private Object stringValueToObject(String s) {
		switch( this ) {
		case BOOLEAN : 
			return Boolean.valueOf(s); // "true" (ignore case) / other = false
			
        case BYTE :
            return Byte.valueOf(s); // throws NumberFormatException
        case SHORT :
            return Short.valueOf(s); // throws NumberFormatException
        case INT :
            return Integer.valueOf(s); // throws NumberFormatException
        case LONG :
            return Long.valueOf(s); // throws NumberFormatException
        
        case FLOAT :
            return Float.valueOf(s); // throws NumberFormatException
        case DOUBLE :
            return Double.valueOf(s); // throws NumberFormatException
               
        case BIGDECIMAL : 
            return new BigDecimal(s); // throws NumberFormatException

        case DATE : 
            return java.sql.Date.valueOf(s); // "yyyy-mm-dd" ( throws IllegalArgumentException ) 
        case TIMESTAMP :
            return java.sql.Timestamp.valueOf(s); // "yyyy-mm-dd hh:mm:ss.ffffff" ( throws IllegalArgumentException )
        case TIME : 
            return java.sql.Time.valueOf(s); // "hh:mm:ss" ( throws IllegalArgumentException )

        default :
            throw new TelosysPersistenceException( "Unknowned type " );
            
		}
	}
	
	private final static HashMap<String,CriterionType> map = new HashMap<String,CriterionType>() ;
	static {
		map.put(Boolean.class.getCanonicalName(), BOOLEAN);
		map.put(boolean.class.getCanonicalName(), BOOLEAN);

		map.put(Byte.class.getCanonicalName(), BYTE);
		map.put(byte.class.getCanonicalName(), BYTE);
		map.put(Short.class.getCanonicalName(), SHORT);
		map.put(short.class.getCanonicalName(), SHORT);
		map.put(Integer.class.getCanonicalName(), INT);
		map.put(int.class.getCanonicalName(), INT);
		map.put(Long.class.getCanonicalName(), LONG);
		map.put(long.class.getCanonicalName(), LONG);

		map.put(Float.class.getCanonicalName(),  FLOAT);
		map.put(float.class.getCanonicalName(),  FLOAT);
		map.put(Double.class.getCanonicalName(), DOUBLE);
		map.put(double.class.getCanonicalName(), DOUBLE);

		map.put(BigDecimal.class.getCanonicalName(), BIGDECIMAL);
		
		map.put(java.util.Date.class.getCanonicalName(), DATE); 
		map.put(java.sql.Date.class.getCanonicalName(), DATE);
		map.put(java.sql.Timestamp.class.getCanonicalName(), TIMESTAMP);
		map.put(java.sql.Time.class.getCanonicalName(), TIME);
		
		map.put(String.class.getCanonicalName(), STRING);
		
	}
	
	public final static CriterionType typeForClass(Class<?> clazz) {
		
		CriterionType criterionType = map.get(clazz.getCanonicalName());
		if ( criterionType != null ) {
			return criterionType ;
		}
		else {
			return UNKNOWN ;
		}
	}
}
